<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Array.from方法</title>
</head>
<body>
  <script>
    /**
    *Array.from方法用于将俩类对象转换为真正的数组：类数组的对象(array-like-object) , 可遍历(iterable)的对象(包括es6新增的
    *数据结构set 和Map)
    */
    var arrayLike = {
      '0': 'a',
      '1': 'b',
      '2': 'c',
      length: 3
    }
    // ES5的写法
    var arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c']
    // es6写法
    var arr2 = Array.from(arrayLike) // ['a', 'b', 'c']
    /**
     * 实际应用中，常见的类似数组的对象是DOM操作返回的NodeList集合，以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。
     * 其二：只要部署了Iterator接口的数据结构都是可遍历的，，Array.from都能生效。
    */
   Array.from('hello')
   // ['h', 'e', 'l', 'l', 'o']
   var nameSet = new Set(['a','b'])
   Array.from(nameSet) // ['a', 'b']
   // 上面代码中，字符串和Set结构都具有Iterator接口，因此可以被转化为数组。
   // 如果参数是一个真正的数组，Array.from会返回一个一模一样的新数组
   Array.from([1,2,3])
   // [1,2,3]
   var list = [{a: '1'}, [1,2,3], 8]
   var lol = Array.from(list)

   lol[1] = [3,2,1]
   console.log(lol)
   console.log(list)
   // 值得提醒的是，扩展运算符(...)也可以将某些数据结构转为数组。
   /**
    * 扩展运算符背后调用的是遍历器接口（Symbol.iterator），如果一个对象没有部署这个接口，就无法转换。
    * Array.from方法还支持类似数组的对象。所谓类似数组的对象，
    * 本质特征只有一点，即必须有length属性。
    * 因此，任何有length属性的对象，都可以通过Array.from方法转为数组，而此时扩展运算符就无法转换。
    *Array.from还可以接受第二个参数，作用雷士于数组的map方法，用来对每个元素进行处理，将处理后的值放入返回的数组
   */
    Array.from(arrayLike, x => x * x)
    // 等同于
    Array.from(arrayLike).map( x => x * x)
    Array.from([1,2,3], (x) => x * x) // [1,4,9]
    // 如果map函数里面用到了this关键字，还可以传入Array.from的第三个参数，用来绑定this
    /**
     * Array.from可以将各种值转为真正的数组，并且还提供map功能，这实际上意味着，只要有一个原始的数据结构
     * 你就可以先对它的值进行处理，然后转成规范的数组结构，进而就可以使用数量众多的数组方法。
    */
  </script>
</body>
</html>